package com.rpoonolly.simplegame.mapio.jsoncoders;

import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;

import org.json.simple.JSONArray;
import org.json.simple.JSONObject;

import com.rpoonolly.simplegame.Config;
import com.rpoonolly.simplegame.core.aabb.AABBEntity;
import com.rpoonolly.simplegame.core.aabb.EntityGameMap;

public class EntityMapJSONCoder extends JSONCoder<EntityGameMap<AABBEntity>>{
	private static EntityMapJSONCoder singletonInstance;
	private Map<String, JSONCoder<AABBEntity>> entityCoderMap; 
	
	private EntityMapJSONCoder() {
		entityCoderMap = new HashMap<String, JSONCoder<AABBEntity>>();
		entityCoderMap.put(Config.ENT_GRP_WORLD_OBJS, AABBEntityJSONCoder.getInstance());
		
	}

	public static EntityMapJSONCoder getInstance() {
		if (singletonInstance == null) {
			singletonInstance = new EntityMapJSONCoder();
		}

		return singletonInstance;
	}

	@SuppressWarnings("unchecked")
	@Override
	public JSONObject encode(EntityGameMap<AABBEntity> entGameMap) throws IOException {
		Map<String, List<AABBEntity>> entMap = entGameMap.getEntities();
		List<AABBEntity> ents;
		
		JSONObject jsonEntMap = new JSONObject();
		JSONArray jsonEnts;
		JSONCoder<AABBEntity> entCoder;
		
		for(String entGroup : entMap.keySet()) {
			ents = entMap.get(entGroup);
			jsonEnts = new JSONArray();
			
			entCoder = entityCoderMap.get(entGroup);
			for(AABBEntity ent : ents) {
				jsonEnts.add(entCoder.encode(ent));
			}
			jsonEntMap.put(entGroup, jsonEnts);
		}
		
		return jsonEntMap;
	}

	@SuppressWarnings("unchecked")
	@Override
	public EntityGameMap<AABBEntity> decode(JSONObject jsonEntMap) throws IOException {
		Map<String, List<AABBEntity>> entMap = new ConcurrentHashMap<String, List<AABBEntity>>();
		List<AABBEntity> ents;
		
		JSONArray jsonEnts;
		JSONCoder<AABBEntity> entCoder;
		List<String> jsonEntGroups = (List<String>) jsonEntMap.keySet();
		
		for(String entGroup : jsonEntGroups) {
			jsonEnts = (JSONArray) jsonEntMap.get(entGroup);
			entCoder = entityCoderMap.get(entGroup);
			
			ents = new CopyOnWriteArrayList<AABBEntity>();
			for(Object obj : jsonEnts) {
				ents.add(entCoder.decode((JSONObject) obj));
			}
			entMap.put(entGroup, ents);
		}
		
		return new EntityGameMap<AABBEntity>(entMap);
	}
}
